package com.koron.ticket.work.logicticket.firstlevelhotwork.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.koron.bean.base.Response;
import com.koron.bean.workflow.RedirectQuery;
import com.koron.ticket.utils.StringUtils;
import com.koron.ticket.work.common.bean.FifteenTables;
import com.koron.ticket.work.common.bean.FourteenTables;
import com.koron.ticket.work.common.bean.Print;
import com.koron.ticket.work.common.service.FifteenTablesService;
import com.koron.ticket.work.common.service.FourteenTablesService;
import com.koron.ticket.work.common.service.OrderChangeStatusService;
import com.koron.ticket.work.enums.TicketNodeStatus;
import com.koron.ticket.work.enums.TicketStatus;
import com.koron.ticket.work.enums.TicketType;
import com.koron.ticket.work.enums.WorkFlowType;
import com.koron.ticket.work.workPermit.bean.WorkPermit;
import com.koron.ticket.work.workPermit.bean.WorkPermitQuery;
import com.koron.ticket.work.workPermit.service.WorkPermitService;
import com.koron.ticket.work.workend.bean.WorkEnd;
import com.koron.ticket.work.workend.bean.WorkEndQuery;
import com.koron.ticket.work.workend.service.WorkEndService;
import com.koron.ticket.work.workflow.bean.WorkFlow;
import com.koron.ticket.work.workflow.bean.WorkFlowQuery;
import com.koron.ticket.work.workflow.service.WorkFlowService;
import com.koron.ticket.work.workinfo.bean.WorkInfo;
import com.koron.ticket.work.workinfo.bean.WorkInfoQuery;
import com.koron.ticket.work.workinfo.service.WorkInfoService;
import com.koron.ticket.work.worklocation.bean.WorkLocationBean;
import com.koron.ticket.work.worklocation.service.WorkLocationService;
import com.koron.ticket.work.workteam.bean.WorkTeam;
import com.koron.ticket.work.workteam.bean.WorkTeamQuery;
import com.koron.ticket.work.workteam.service.WorkTeamService;
import com.koron.ticket.work.workticket.bean.WorkTicket;
import com.koron.ticket.work.workticket.bean.WorkTicketQuery;
import com.koron.ticket.work.workticket.service.WorkTicketService;
import org.koron.ebs.mybatis.SessionFactory;
import org.koron.ebs.mybatis.TaskAnnotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class FirstLevelHotWorkService {

    @Autowired
    private FourteenTablesService fourteenTablesService;

    @Autowired
    private FifteenTablesService fifteenTablesService;

    @Autowired
    private WorkTicketService workTicketService;

    @Autowired
    private WorkInfoService workInfoService;

    @Autowired
    private WorkTeamService workTeamService;

    @Autowired
    private WorkLocationService worklocationservice;

    @Autowired
    private WorkFlowService workFlowService;

    @Autowired
    private WorkPermitService workPermitService;

    @Autowired
    private WorkEndService workEndService;

    // 变更工单状态
    @Autowired
    private OrderChangeStatusService orderChangeStatusService;

    /**
     * 保存数据
     * 1. id为空是新增
     * 2. id不为空是更新
     *
     * @param factory
     * @param fourteenTables
     * @return Response对象
     * @version 1.0
     * @see Response
     * @see FifteenTables
     */
    @TaskAnnotation("writeSave")
    public Response writeSave(SessionFactory factory, FourteenTables fourteenTables) {
        String workTicketId = fourteenTablesService.writeSave(factory, fourteenTables);
        return Response.success(workTicketId);
    }

    @TaskAnnotation("getPrintData")
    public List<Print> getPrintData(SessionFactory factory, String id) {
        List<Print> result = new ArrayList<>();
        Print print = new Print();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");

        WorkTicketQuery workTicketQuery = new WorkTicketQuery();
        workTicketQuery.setId(id);
        WorkTicket workTicket = workTicketService.getSingle(factory, workTicketQuery);
        Integer status = workTicket.getStatus();

        WorkInfoQuery workInfoQuery = new WorkInfoQuery();
        workInfoQuery.setWorkTicketId(id);
        WorkInfo workInfo = workInfoService.getSingle(factory, workInfoQuery);

        WorkTeamQuery workTeamQuery = new WorkTeamQuery();
        workTeamQuery.setWorkTicketId(id);
        List<WorkTeam> workTeamList = workTeamService.getList(factory, workTeamQuery);

        WorkFlowQuery workFlowQuery = new WorkFlowQuery();
        workFlowQuery.setWorkTicketId(id);
        List<WorkFlow> workFlowList = workFlowService.getList(factory, workFlowQuery);

        WorkPermitQuery workPermitQuery = new WorkPermitQuery();
        workPermitQuery.setWorkTicketId(id);
        WorkPermit workPermit = workPermitService.getSingle(factory, workPermitQuery);

        WorkEndQuery workEndQuery = new WorkEndQuery();
        workEndQuery.setWorkTicketId(id);
        List<WorkEnd> workEndList = workEndService.getList(factory, workEndQuery);
        WorkEnd workEnd = new WorkEnd();
        // 20211130: 兼容工作待终结数据为空的情况
        if (workEndList.size() > 0) {
            workEnd = workEndList.get(0);
        }


        // 1. 开票人单位名称
        String type = workTicket.getType();
        if (type.equals(TicketType.FirstLevelHotWork)) {
            print.setUnitName(workTicket.getUnitName() + "一级动火工作票");
        } else {
            print.setUnitName(workTicket.getUnitName() + "二级动火工作票");
        }
        // 2. 工作票号
        print.setCode(workTicket.getCode());
        // 3. 动火部门名称
        print.setDepartmentName(workInfo.getDepartmentName());
        // 4. 工作班组名称
        String workTeamListString = "";
        if (workTeamList.size() > 0) {
            workTeamListString = workTeamList.stream().map(WorkTeam::getWorkTeamName).collect(Collectors.joining(","));
        }
        print.setWorkTeamNameListString(workTeamListString);
        // 5. 工作负责人名称
        print.setDirectorName(workTicket.getDirectorName());
        // 6. 工作地点名称
        List<WorkLocationBean> worklocationlist = worklocationservice.getList(factory, id);
        String worklocationlistStr = "";
        if (worklocationlist.size() > 0) {
            worklocationlistStr = worklocationlist.stream().map(WorkLocationBean::getLocationName).collect(Collectors.joining(","));
        }
        print.setLocationName(worklocationlistStr);
//        print.setLocationName(workTicket.getLocationName());
        // 7. 设备名称
        print.setEquipmentName(workInfo.getEquipmentName());
        // 8. 工作内容
        print.setContent(workTicket.getContent());
        // 9. 计划开始时间
        if (workTicket.getEstimatedStartTime() != null) {
            // 兼容计划开始时间为空的情况
            print.setEstimatedStartTime(DateUtil.format(workTicket.getEstimatedStartTime(), "yyyy年MM月dd日 HH时mm分"));
        }
        // 10. 计划结束时间
        if (workTicket.getEstimatedEndTime() != null) {
            // 兼容计划结束时间为空的情况
            print.setEstimatedEndTime(DateUtil.format(workTicket.getEstimatedEndTime(), "yyyy年MM月dd日 HH时mm分"));
        }
        // 11. 安全措施
        print.setSafetyMeasures(workInfo.getSafetyMeasures());
        // 12. 检修安全措施
        print.setSafetyMeasuresRepair(workInfo.getSafetyMeasuresRepair());
        // 13. 签发阶段
        if (status >= TicketStatus.SIGN.getStatus()) {
            for (WorkFlow workFlow : workFlowList) {
                if (workFlow.getStatus() == TicketStatus.SIGN.getStatus()) {
                    if(workFlow.getName() == null || workFlow.getOperationTime() == null){
                        continue;
                    }
                    // 13.1 工作票签发人
                    print.setSignName(workFlow.getName());
                    // 13.2 签发时间
                    Opt<String> optdate = Opt.of(DateUtil.format(workFlow.getOperationTime(), "yyyy年MM月dd日 HH时mm分"));
                    print.setSignTime(optdate.orElse(""));
                    break;
                }
            }

        }
        // 14. 会签阶段--二级动火工作票才有
        if (type.equals(TicketType.SecondLevelHotWork.getType())) {
            if (status >= TicketStatus.COUNTERSIGN.getStatus()) {
                for (WorkFlow workFlow : workFlowList) {
                    if (workFlow.getStatus() == TicketStatus.COUNTERSIGN.getStatus()) {
                        // 14.1 工作票会签人
                        print.setCountersignName(workFlow.getName());
                        // todo 这里会报空指针异常,修改方式如下
                        //Opt<String> optdate = Opt.of(DateUtil.format(workFlow.getOperationTime(), "yyyy年MM月dd日 HH时mm分"));
                        //print.setCountersignTime(optdate.orElse(""));

                        String format = DateUtil.format(workFlow.getOperationTime(), "yyyy年MM月dd日 HH时mm分");
                        print.setCountersignTime(format != null ? format : "");
                        break;
                    }
                }
            }
        }

        // 15. 待许可阶段
        if (status >= TicketStatus.PERMIT.getStatus()) {
            // 15.1 各种签名信息
            for (WorkFlow workFlow : workFlowList) {
                if (workFlow.getStatus() == TicketStatus.PERMIT.getStatus()) {
                    if (workFlow.getType().equals("name0")) {
                        print.setPermitName(workFlow.getName());
                    } else if (workFlow.getType().equals("name1")) {
                        print.setDirectorNameForPermit(workFlow.getName());
                    } else if (workFlow.getType().equals("name2")) {
                        print.setFireSupervisor(workFlow.getName());
                    } else if (workFlow.getType().equals("name3")) {
                        print.setHotWorkExecutor(workFlow.getName());
                    } else if (workFlow.getType().equals("name5")) {
                        print.setPermitName2(workFlow.getName());
                    } else if (workFlow.getType().equals("工作票签发人")) {
                        print.setSignNameForPermit(workFlow.getName());
                    } else if (workFlow.getType().equals("name4")) {
                        print.setPermitTrackName(workFlow.getName());
                    }
                }

            }
            // 15.2 动火开始时间
            if (workPermit.getWorkTime() != null) {
                // 兼容工作开始时间为空的情况
                print.setWorkTime(DateUtil.format(workPermit.getWorkTime(), "yyyy年MM月dd日 HH时mm分"));
            }
        }
        // 16. 工作待终结
        if (status >= TicketStatus.WORK_END.getStatus()) {
            // 16.1 各种签名信息
            for (WorkFlow workFlow : workFlowList) {
                if (workFlow.getStatus() == TicketStatus.WORK_END.getStatus()) {
                    if (workFlow.getType().equals("name2")) {
                        print.setPermitNameForWorkEnd(workFlow.getName());
                    } else if (workFlow.getType().equals("name0")) {
                        print.setDirectorNameForWorkEnd(workFlow.getName());
                    } else if (workFlow.getType().equals("消防监护人")) {
                        print.setFireSupervisorForWorkEnd(workFlow.getName());
                    } else if (workFlow.getType().equals("name1")) {
                        print.setHotWorkExecutorForWorkEnd(workFlow.getName());
                    }
                }

            }
            // 16.2 工作结束时间
            if (status >= TicketStatus.ARCHIVED.getStatus() && workEnd.getEndTime() != null) {
                // 兼容工作开始时间为空的情况
                print.setEndTimeForWorkEnd(DateUtil.format(workEnd.getEndTime(), "yyyy年MM月dd日 HH时mm分"));
            }
            // 16.3 备注
            print.setDescription(workEnd.getEndDescription());
        }

        result.add(print);
        return result;
    }

    @TaskAnnotation("writeSubmit")
    public Response writeSubmit(SessionFactory factory, FourteenTables fourteenTables) {
        String workTicketId = fourteenTablesService.writeSubmitByWorkFlowTypeAndStatus(
                factory, fourteenTables, WorkFlowType.FirstLevelHotWork.getWorkFlow(), TicketStatus.SIGN.getStatus());
        return Response.success(workTicketId);
    }

    @TaskAnnotation("signSave")
    public Response signSave(SessionFactory factory, WorkFlow workFlow) {
        workFlowService.save(factory, workFlow);
        return Response.success("提交/保存成功");
    }

    @TaskAnnotation("acceptSave")
    public Response acceptSave(SessionFactory factory, WorkFlow workFlow) {
        workFlowService.save(factory, workFlow);
        return Response.success("提交/保存成功");
    }

    @TaskAnnotation("permitSave")
    public Response permitSave(SessionFactory factory, WorkPermit workPermit) {
        fifteenTablesService.permitSave(factory, workPermit);
        return Response.success("待许可-提交/保存成功");
    }

    @TaskAnnotation("workEndSave")
    public Response workEndSave(SessionFactory factory, WorkEnd workEnd) {
        fifteenTablesService.endSaveWithStatus(factory, workEnd, TicketStatus.WORK_END.getStatus());
        return Response.success("工作待终结-提交/保存成功");
    }

    @TaskAnnotation("workflowUpdate")
    public Response workflowUpdate(SessionFactory factory, RedirectQuery redirectQuery) throws ParseException {
        Integer operation = redirectQuery.getOperation();
        String workTicketId = redirectQuery.getDataId();
        WorkTicketQuery workTicketQuery = new WorkTicketQuery();
        workTicketQuery.setId(workTicketId);
        WorkTicket workTicket = workTicketService.getSingle(factory, workTicketQuery);
        Integer status = workTicket.getStatus();
        String type = workTicket.getType();

        // 1. 如果被驳回，返回对应状态，仅删除签名的数据，其他的数据不做处理
        if (operation == 1) {
            String rejectNodeCode = redirectQuery.getRejectNodeCode();
            rejectNodeCode = rejectNodeCode.replace("call-", "");
            if (rejectNodeCode.equals(TicketNodeStatus.WRITE.getNodeName())) {
                Integer rejectStatus = TicketStatus.WRITE.getStatus();
                fifteenTablesService.clenWorkFlowByStatus(factory, workTicketId, rejectStatus);
                workPermitService.deleteByWorkTicketId(factory, workTicketId);//删除许可信息
                workTicket.setStatus(rejectStatus);
            } else if (rejectNodeCode.equals(TicketNodeStatus.SIGN.getNodeName())) {
                Integer rejectStatus = TicketStatus.SIGN.getStatus();
                fifteenTablesService.clenWorkFlowByStatus(factory, workTicketId, rejectStatus);
                workPermitService.deleteByWorkTicketId(factory, workTicketId);//删除许可信息
                workTicket.setStatus(rejectStatus);
            } else if (rejectNodeCode.equals(TicketNodeStatus.ACCEPT.getNodeName())) {
                Integer rejectStatus = TicketStatus.ACCEPT.getStatus();
                fifteenTablesService.clenWorkFlowByStatus(factory, workTicketId, rejectStatus);
                workPermitService.deleteByWorkTicketId(factory, workTicketId);//删除许可信息
                workTicket.setStatus(rejectStatus);
            } else if (rejectNodeCode.equals(TicketNodeStatus.PERMIT.getNodeName())) {
                Integer rejectStatus = TicketStatus.PERMIT.getStatus();
                fifteenTablesService.clenWorkFlowByStatus(factory, workTicketId, rejectStatus);
                // 20211111: 如何是待许可状态，讲预览标志设置成未预览
                workTicket.setPreviewFlag(1);
                workTicket.setStatus(rejectStatus);
            }
            workTicketService.update(factory, workTicket);
        } // 2. 如果通过，工作票进入下一个状态，并根据状态的不同进行不同的操作
        else if (operation == 32) {
            String formVariables = redirectQuery.getFormVariables();
            // 2.1 如果是签发状态，1.保存签名信息；2.设置工作票号；3.跳过会签阶段
            if (status.equals(TicketStatus.SIGN.getStatus())) {
                // 保存签名数据
                fifteenTablesService.saveWorkFLow(factory, formVariables);
                // 设置工作票号
                if (StrUtil.isBlank(workTicket.getCode())) {
                    String code = fifteenTablesService.getLastCodeByUnitAndTicketTypeNew(factory, workTicket.getUnit(), type);
                    if (StringUtils.isEmpty(code)) {
                        return Response.fail("工作票票号生成有问题，请联系运维人员");
                    }
                    workTicket.setCode(code);
                }
                // 跳过会签阶段
                status = status + 1;
            } // 2.3 如果是待接收状态：1.保存签名信息；2.将预览标志设为未预览
            else if (status.equals(TicketStatus.ACCEPT.getStatus())) {
                // 保存签名信息
                fifteenTablesService.saveWorkFLow(factory, formVariables);
                // 将预览标志设为未预览
                workTicket.setPreviewFlag(1);
            }
            // 2.4 如果是待许可状态，保存签名信息，以及待许可信息
            else if (status.equals(TicketStatus.PERMIT.getStatus())) {
                // 保存许可信息
                WorkPermit workPermit = JSONObject.parseObject(formVariables, WorkPermit.class);
                workPermit.setId(workPermit.getWorkPermitId());
                workPermit.setPermitTime(new Date());
                workPermitService.save(factory, workPermit);
                // 保存签名信息
                List<WorkFlow> workFlowList = workPermit.getWorkFlowList();
                if (workFlowList != null && workFlowList.size() > 0) {
                    for (WorkFlow workFLow : workFlowList) {
                        workFlowService.save(factory, workFLow);
                    }
                }
            }
            // 许可后变更工单状态为执行中
            orderChangeStatusService.changeOrderStatus(workTicket.getOrderType(), workTicket.getOrderId());
            // 3. 状态更新，更新主票
            workTicket.setStatus(status + 1);
            workTicketService.update(factory, workTicket);
        } else if (operation == 256) {
            Integer rejectStatus = TicketStatus.WRITE.getStatus();
            fifteenTablesService.clenWorkFlowByStatus(factory, workTicketId, rejectStatus);
            workPermitService.deleteByWorkTicketId(factory, workTicketId);//删除许可信息
            workTicket.setStatus(rejectStatus);
            workTicketService.update(factory, workTicket);
        } else {
            return Response.fail("操作类型为：" + operation + ",请联系运维人员");
        }

        return Response.success("电气第一种工作票提交成功");
    }

    @TaskAnnotation("workflowUpdateEnd")
    public Response workflowUpdateEnd(SessionFactory factory, RedirectQuery redirectQuery) throws ParseException {
        fifteenTablesService.workflowUpdateEnd(factory, redirectQuery);
        return Response.success("工作票已归档");
    }

    @TaskAnnotation("workflowUpdateCancel")
    public Response workflowUpdateCancel(SessionFactory factory, RedirectQuery redirectQuery) {
        fifteenTablesService.workflowUpdateCancel(factory, redirectQuery);
        return Response.success("工作票已作废");
    }

    public FourteenTables add() {
        FourteenTables fourteenTables = fourteenTablesService.addByType(TicketType.FirstLevelHotWork.getType());
        return fourteenTables;
    }

    public FourteenTables getById(SessionFactory factory, String id) {
        FourteenTables fourteenTables = fifteenTablesService.getById(factory, id);
        return fourteenTables;
    }

    public void deleteById(SessionFactory factory, String id) {
        fourteenTablesService.deleteById(factory, id);
    }
}
